﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//SortedList好像也是一种排序的链表
class ProgramSortedList
{
    static void MainsortedList(string[] args)
    {
        SortedListTest();//演示的demo
        //简单总结一下用法
        //1，创建
        SortedList sortedList2 = new();//这个方法添加的key和value应该是引用类型object
        SortedList<int, int> sortedList = new();
        //增
        sortedList.Add(1, 2);
        sortedList.Add(3, 4);
        sortedList.Add(5, 6);
        //查
        sortedList.TryGetValue(1, out int val);

        foreach(int i in sortedList.Keys)
        {
            Console.WriteLine(sortedList[i]);
        }
        sortedList.ContainsKey(2);
        sortedList.ContainsValue(2);
        

        sortedList.GetKeyAtIndex(2);
        
        sortedList.GetValueAtIndex(2);

        //获取对应值的index
        sortedList.IndexOfKey(2);
        sortedList.IndexOfValue(2);

        //删
        sortedList.Remove(1);//删除key=1
        sortedList.RemoveAt(0); 






        
    }
    

    //封装两个简单方法，方便后续验证使用
    /// <summary>
    /// 分隔线
    /// </summary>
    static void 分隔线()
    {
        Console.WriteLine("\n ------------------------------------------- \n");
    }

    /// <summary>
    /// 遍历 所有 键/值对
    /// </summary>
    static void FKeyValue(IDictionary iDictionary)
    {
        foreach (DictionaryEntry de in iDictionary)
        {
            Console.Write("key: {0} , value: {1}\n", de.Key, de.Value);
        }
        分隔线();
    }

    /// <summary>
    /// 排序列表
    /// </summary>
    static void SortedListTest()
    {
        SortedList sortedList = new SortedList();
        Console.WriteLine("列表自动按照键来排列： ");
        //SortedList可以为泛型
        //SortedList<int, string> sl2 = new SortedList<int, string>(); 
        sortedList.Add(1, 'a');
        sortedList.Add(0, 'A');
        sortedList.Add(2, 'b');
        sortedList.Add(4, 'b');
        sortedList.Add(3, true);
        //SortedList无法添加不同数据类型的键，因为这将导致无法通过键来排序
        //sortedList.Add('c', 3);
        FKeyValue(sortedList);
        Console.WriteLine("\n");
        Console.WriteLine("列表容量： " + sortedList.Capacity);
        Console.WriteLine("元素个数： " + sortedList.Count);
        Console.WriteLine("固定大小： " + sortedList.IsFixedSize);
        Console.WriteLine("是否只读： " + sortedList.IsReadOnly);
        Console.WriteLine("\n");
        Console.WriteLine("1.通过keys遍历键：");
        foreach (var k in sortedList.Keys)
        {
            Console.Write("key: " + k + " / ");
            //顺便通过键遍历值
            Console.Write("value: " + sortedList[k] + " \n");
        }
        Console.WriteLine("\n");
        Console.WriteLine("2.通过values遍历值：");
        foreach (var v in sortedList.Values)
        {
            Console.Write("value: " + v + "\n ");
            //无法通过值遍历键,除非键和值相同
            //Console.Write("key: " + sl[v] + " \n");
        }
        Console.WriteLine("\n");
        Console.WriteLine("3.同时遍历键/值对：");
        foreach (DictionaryEntry de in sortedList)
        {
            Console.Write("key: " + de.Key + " / ");
            Console.Write("value: " + de.Value + " \n");
        }
        Console.WriteLine("\n");

        Console.WriteLine("6.获取指定索引处的值：");
        Console.WriteLine("索引0的值： " + sortedList.GetByIndex(0));
        Console.WriteLine("索引1的值： " + sortedList.GetByIndex(1));
        //超出索引范围时，编译会报错
        //Console.WriteLine("索引100的值： " + sl.GetByIndex(100));
        Console.WriteLine("\n");

        Console.WriteLine("7.获取指定索引处的键：");
        Console.WriteLine("索引0的键： " + sortedList.GetKey(0));
        Console.WriteLine("索引1的键： " + sortedList.GetKey(1));
        //超出索引范围时，编译会报错
        //Console.WriteLine("索引100的键： " + sl.GetKey(100));
        Console.WriteLine("\n");

        Console.WriteLine("8.获取所有键的列表：");
        IList lik = sortedList.GetKeyList();
        foreach (var i in lik)
        {
            Console.Write("键：" + i + " / ");
            //可以通过键获取对应的值
            Console.Write("值：" + sortedList[i] + "\n");
        }
        Console.WriteLine("\n");

        Console.WriteLine("9.获取所有值的列表：");
        IList liv = sortedList.GetValueList();
        foreach (var i in liv)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine("\n");

        Console.WriteLine("10.获取指定键的索引：");
        Console.WriteLine("key(2)的索引： " + sortedList.IndexOfKey(2));
        //在同数据类型的情况下，查询不存在的键，编译不会报错,会返回-1，表示不存在
        Console.WriteLine("key(10)的索引： " + sortedList.IndexOfKey(10));
        //获取不同数据类型的键的索引时，编译会报错
        //Console.WriteLine("key(a)的索引： " + sl.IndexOfKey('a'));
        Console.WriteLine("\n");

        Console.WriteLine("11.获取指定值的索引：");
        //查询不存在的值，编译不会报错,会返回 - 1，表示不存在
        Console.WriteLine("value(10)的索引： " + sortedList.IndexOfValue(10));
        Console.WriteLine("value(A)的索引： " + sortedList.IndexOfValue('A'));

        Console.WriteLine("12.移除带有指定键的元素：");
        Console.WriteLine("移除key(3)： ");
        sortedList.Remove(3);
        Console.WriteLine("移除key(100)： ");
        //在同数据类型的情况下，移除不存在的键，编译不会报错
        sortedList.Remove(100);
        Console.WriteLine("移除key(a)： ");
        //移除不同数据类型的键，编译会报错
        //sl.Remove('a');
        FKeyValue(sortedList);
        Console.WriteLine("\n");

        Console.WriteLine("13.移除指定索引处的元素：");
        Console.WriteLine("索引0的元素： ");
        sortedList.RemoveAt(0);
        Console.WriteLine("索引100的元素： ");
        //超出索引范围时，编译会报错
        //sl.RemoveAt(100);
        FKeyValue(sortedList);


        Console.WriteLine("14.根据当前元素的实际个数分配列表容量：");
        Console.WriteLine("设置前列表容量： " + sortedList.Capacity);
        Console.WriteLine("增加设置前列表容量： " + (sortedList.Capacity = 120));
        Console.WriteLine("设置前元素个数： " + sortedList.Count);
        //即使设置了容量，也会根据实际添加数自动扩容
        sortedList.TrimToSize();
        sortedList.Add(10, 10);
        Console.WriteLine("设置后列表容量： " + sortedList.Capacity);
        Console.WriteLine("设置后元素个数： " + sortedList.Count);
    }
}

